﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Fetion.Core
{
    /// <summary>
    /// 消息句柄描述对象
    /// </summary>
    public class MessageHandlerArgs
    {
        /// <summary>
        /// 构建对象
        /// </summary>
        public MessageHandlerArgs()
        {
            Cancel = false;
        }
        /// <summary>
        /// 消息对象
        /// </summary>
        public object Message;
        /// <summary>
        /// 是否取消控制器转发
        /// </summary>
        public bool Cancel;
        
    }
    /// <summary>
    /// 消息处理对象描述,提供给ChannelController使用,方便消息自动转发
    /// </summary>
    public interface IMessageHandler
    {
       /// <summary>
       /// 消息处理过程
       /// </summary>
       /// <param name="adapter">tcpchannel</param>
       /// <param name="message">消息对象</param>
        void ProcessMessage(TcpChannel adapter, MessageHandlerArgs message);
       
    }
    class MessageHandlerAction
    {
        public IMessageHandler Handler;
       
        
        public System.Reflection.MethodInfo Method;
        public Type Type;
        private static Dictionary<Type, List<MessageHandlerAction>> mHandlers = new Dictionary<Type, List<MessageHandlerAction>>(512);
        public static IList<MessageHandlerAction> GetActions(IMessageHandler handler)
        {
            lock (mHandlers)
            {
                List<MessageHandlerAction> results=null;
                Type type = handler.GetType();
                if (mHandlers.ContainsKey(type))
                {
                    results = mHandlers[type];
                    foreach (MessageHandlerAction action in results)
                    {
                        action.Handler = handler;
                    }
                }
                if (results == null)
                {
                    results = new List<MessageHandlerAction>();
                    foreach (System.Reflection.MethodInfo method in type.GetMethods(System.Reflection.BindingFlags.Instance
                        | System.Reflection.BindingFlags.Public))
                    {
                        System.Reflection.ParameterInfo[] parameters = method.GetParameters();
                        if (parameters.Length == 2)
                        {
                            if (parameters[0].ParameterType == typeof(TcpChannel))
                            {
                                MessageHandlerAction action = new MessageHandlerAction();
                                action.Handler = handler;
                                action.Method = method;
                                action.Type = parameters[1].ParameterType;
                                results.Add(action);
                            }
                        }
                    }
                }

                return results;
            }

           
        }
        public void Execute(TcpChannel  channel, object message)
        {
            MessageHandlerArgs e = new MessageHandlerArgs();
            e.Message = message;
            e.Cancel = false;
            Handler.ProcessMessage(channel, e);
            if (!e.Cancel)
                Method.Invoke(Handler, new object[] { channel, message });
                

        }
    }
}
